home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Prefs / icon.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  16KB  |  476 lines

  1. /*
  2.  * icon.c  V3.1
  3.  *
  4.  * TM Icon object class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. #define PROPCHUNKS 2
  20. static const ULONG PropChunkTable[2 * PROPCHUNKS] = {
  21.  ID_TMIC, ID_DATA,
  22.  ID_TMIC, ID_NAME,
  23. };
  24. static const char *TextTitle;
  25. static const char *HelpExecObject;
  26. static const char *HelpImageObject;
  27. static const char *HelpSoundObject;
  28. static const char *HelpPosition;
  29. static const char *TextShowName;
  30. static const char *HelpShowName;
  31.  
  32. /* Icon class instance data */
  33. struct IconClassData {
  34.  ULONG              icd_Flags;
  35.  ULONG              icd_LeftEdge;
  36.  ULONG              icd_TopEdge;
  37.  struct AttachData *icd_ExecObject;
  38.  struct AttachData *icd_ImageObject;
  39.  struct AttachData *icd_SoundObject;
  40.  Object            *icd_Active;
  41.  Object            *icd_ExecDrop;
  42.  Object            *icd_ImageDrop;
  43.  Object            *icd_SoundDrop;
  44.  Object            *icd_Position;
  45.  Object            *icd_ShowName;
  46. };
  47. #define TYPED_INST_DATA(cl, o) ((struct IconClassData *) INST_DATA((cl), (o)))
  48.  
  49. /* Icon class method: OM_NEW */
  50. #undef  DEBUGFUNCTION
  51. #define DEBUGFUNCTION IconClassNew
  52. static ULONG IconClassNew(Class *cl, Object *obj, struct opSet *ops)
  53. {
  54.  ICON_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  55.            PrintTagList(ops->ops_AttrList)))
  56.  
  57.  /* Create object */
  58.  if (obj = (Object *) DoSuperNew(cl, obj,
  59.                                        MUIA_Window_Title, TextTitle,
  60.                                        MUIA_HelpNode,     "IconWindow",
  61.                                        TMA_Type,          TMOBJTYPE_ICON,
  62.                                        TAG_MORE,          ops->ops_AttrList)) {
  63.   struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  64.  
  65.   /* Initialize instance data */
  66.   icd->icd_Flags       = DATA_ICONF_SHOWNAME;
  67.   icd->icd_LeftEdge    = 0;
  68.   icd->icd_TopEdge     = 0;
  69.   icd->icd_ExecObject  = NULL;
  70.   icd->icd_ImageObject = NULL;
  71.   icd->icd_SoundObject = NULL;
  72.   icd->icd_Active      = NULL;
  73.  }
  74.  
  75.  ICON_LOG(LOG1(Result, "0x%08lx", obj))
  76.  
  77.  /* Return pointer to created object */
  78.  return((ULONG) obj);
  79. }
  80.  
  81. /* Icon class method: OM_DISPOSE */
  82. #undef  DEBUGFUNCTION
  83. #define DEBUGFUNCTION IconClassDispose
  84. static ULONG IconClassDispose(Class *cl, Object *obj, Msg msg)
  85. {
  86.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  87.  
  88.  ICON_LOG(LOG1(Disposing, "0x%08lx", obj))
  89.  
  90.  /* Detach objects */
  91.  if (icd->icd_ExecObject)  DoMethod(icd->icd_ExecObject->ad_Object,
  92.                                     TMM_Detach, icd->icd_ExecObject);
  93.  if (icd->icd_ImageObject) DoMethod(icd->icd_ImageObject->ad_Object,
  94.                                     TMM_Detach, icd->icd_ImageObject);
  95.  if (icd->icd_SoundObject) DoMethod(icd->icd_SoundObject->ad_Object,
  96.                                     TMM_Detach, icd->icd_SoundObject);
  97.  
  98.  /* Call SuperClass */
  99.  return(DoSuperMethodA(cl, obj, msg));
  100. }
  101.  
  102. /* Icon class method: TMM_Finish */
  103. #undef  DEBUGFUNCTION
  104. #define DEBUGFUNCTION IconClassFinish
  105. static ULONG IconClassFinish(Class *cl, Object *obj, struct TMP_Finish *tmpf)
  106. {
  107.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  108.  
  109.  ICON_LOG(LOG1(Type, "%ld", tmpf->tmpf_Type))
  110.  
  111.  /* MUI objects allocated? */
  112.  if (icd->icd_Active) {
  113.  
  114.   /* Use or Cancel? */
  115.   if (tmpf->tmpf_Type == TMV_Finish_Use) {
  116.  
  117.    /* Get new attach data */
  118.    icd->icd_ExecObject  = GetAttachData(icd->icd_ExecDrop,  obj,
  119.                                         icd->icd_ExecObject);
  120.    icd->icd_ImageObject = GetAttachData(icd->icd_ImageDrop, obj,
  121.                                         icd->icd_ImageObject);
  122.    icd->icd_SoundObject = GetAttachData(icd->icd_SoundDrop, obj,
  123.                                         icd->icd_SoundObject);
  124.  
  125.    /* Get new position values */
  126.    GetAttr(MUIA_Popposition_XPos, icd->icd_Position,  &icd->icd_LeftEdge);
  127.    GetAttr(MUIA_Popposition_YPos, icd->icd_Position,  &icd->icd_TopEdge);
  128.  
  129.    /* Get new flag status */
  130.    icd->icd_Flags = GetCheckmarkState(icd->icd_ShowName, DATA_ICONF_SHOWNAME);
  131.   }
  132.  
  133.   /* Reset pointer to file name area */
  134.   icd->icd_Active = NULL;
  135.  }
  136.  
  137.  /* Call SuperClass */
  138.  return(DoSuperMethodA(cl, obj, (Msg) tmpf));
  139. }
  140.  
  141. /* Icon class method: TMM_Notify */
  142. #undef  DEBUGFUNCTION
  143. #define DEBUGFUNCTION IconClassNotify
  144. static ULONG IconClassNotify(Class *cl, Object *obj, struct TMP_Notify *tmpn)
  145. {
  146.  ICON_LOG(LOG1(Type, "0x%08lx", tmpn->tmpn_Data->ad_Object))
  147.  
  148.  /* Object deleted? */
  149.  if (tmpn->tmpn_Data->ad_Object == NULL) {
  150.   struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  151.  
  152.   /* Exec, Image or Sound object? */
  153.   if      (icd->icd_ExecObject  == tmpn->tmpn_Data)
  154.    icd->icd_ExecObject  = NULL;
  155.   else if (icd->icd_ImageObject == tmpn->tmpn_Data)
  156.    icd->icd_ImageObject = NULL;
  157.   else
  158.    icd->icd_SoundObject = NULL;
  159.  }
  160.  
  161.  /* Return 1 to indicate that the method is implemented */
  162.  return(1);
  163. }
  164.  
  165. /* Icon class method: TMM_Edit */
  166. #undef  DEBUGFUNCTION
  167. #define DEBUGFUNCTION IconClassEdit
  168. static ULONG IconClassEdit(Class *cl, Object *obj, struct TMP_Edit *tmpe)
  169. {
  170.  struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  171.  
  172.  /* MUI objects allocated? */
  173.  if (icd->icd_Active) {
  174.  
  175.   ICON_LOG(LOG0(Object already active))
  176.  
  177.   /* Yes, forward method to SuperClass */
  178.   DoSuperMethodA(cl, obj, (Msg) tmpe);
  179.  
  180.  /* No, create object edit area */
  181.  } else if (icd->icd_Active =
  182.     VGroup,
  183.      Child, ColGroup(2),
  184.       Child, Label1(TextGlobalExecObject),
  185.       Child, icd->icd_ExecDrop  = NewObject(DropAreaClass->mcc_Class, NULL,
  186.                                           TMA_Type,       TMOBJTYPE_EXEC,
  187.                                           TMA_Attach,     icd->icd_ExecObject,
  188.                                           MUIA_ShortHelp, HelpExecObject,
  189.                                           TAG_DONE),
  190.       Child, Label1(TextGlobalImageObject),
  191.       Child, icd->icd_ImageDrop = NewObject(DropAreaClass->mcc_Class, NULL,
  192.                                           TMA_Type,       TMOBJTYPE_IMAGE,
  193.                                           TMA_Attach,     icd->icd_ImageObject,
  194.                                           MUIA_ShortHelp, HelpImageObject,
  195.                                           TAG_DONE),
  196.       Child, Label1(TextGlobalSoundObject),
  197.       Child, icd->icd_SoundDrop = NewObject(DropAreaClass->mcc_Class, NULL,
  198.                                           TMA_Type,       TMOBJTYPE_SOUND,
  199.                                           TMA_Attach,     icd->icd_SoundObject,
  200.                                           MUIA_ShortHelp, HelpSoundObject,
  201.                                           TAG_DONE),
  202.       Child, Label2(TextGlobalPosition),
  203.       Child, icd->icd_Position  = TMPopPosition(icd->icd_LeftEdge,
  204.                                                 icd->icd_TopEdge,
  205.                                                 HelpPosition),
  206.       End,
  207.      End,
  208.      Child, HGroup,
  209.       Child, HSpace(0),
  210.       Child, Label1(TextShowName),
  211.       Child, icd->icd_ShowName =
  212.        MakeCheckmark(icd->icd_Flags & DATA_ICONF_SHOWNAME, HelpShowName),
  213.       Child, HSpace(0),
  214.      End,
  215.     End) {
  216.  
  217.   ICON_LOG(LOG1(Icon Area, "0x%08lx", icd->icd_Active))
  218.  
  219.   /* Forward method to SuperClass */
  220.   if (DoSuperMethod(cl, obj, TMM_Edit, icd->icd_Active)) {
  221.    struct Screen *screen;
  222.  
  223.    /* SuperClass succeeded, get screen */
  224.    GetAttr(MUIA_Window_Screen, obj, (ULONG *) &screen);
  225.  
  226.    /* Set new Y offset for position gadget */
  227.    SetAttrs(icd->icd_Position,
  228.                              MUIA_Popposition_YOffset, - screen->BarHeight - 1,
  229.                              TAG_DONE);
  230.  
  231.   } else {
  232.  
  233.    /* SuperClass failed, delete file area again */
  234.    MUI_DisposeObject(icd->icd_Active);
  235.    icd->icd_Active = NULL;
  236.   }
  237.  }
  238.  
  239.  ICON_LOG(LOG1(Result, "0x%08lx", icd->icd_Active))
  240.  
  241.  /* Return pointer to file area object to indicate success */
  242.  return((ULONG) icd->icd_Active);
  243. }
  244.  
  245. /* Icon class method: TMM_ParseIFF */
  246. #undef  DEBUGFUNCTION
  247. #define DEBUGFUNCTION IconClassParseIFF
  248. static ULONG IconClassParseIFF(Class *cl, Object *obj,
  249.                                struct TMP_ParseIFF *tmppi)
  250. {
  251.  BOOL rc = FALSE;
  252.  
  253.  ICON_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  254.  
  255.  /* Initialize IFF parser */
  256.  if ((PropChunks(tmppi->tmppi_IFFHandle, PropChunkTable, PROPCHUNKS) == 0) &&
  257.      (StopOnExit(tmppi->tmppi_IFFHandle, ID_TMIC, ID_FORM) == 0) &&
  258.      (ParseIFF(tmppi->tmppi_IFFHandle, IFFPARSE_SCAN) == IFFERR_EOC)) {
  259.   struct StoredProperty *spname;
  260.  
  261.   ICON_LOG(LOG0(FORM TMIC chunk parsed OK))
  262.  
  263.   /* Check for mandatory NAME property */
  264.   if (spname = FindProp(tmppi->tmppi_IFFHandle, ID_TMIC, ID_NAME)) {
  265.    struct StoredProperty *spdata;
  266.  
  267.    ICON_LOG(LOG2(Name, "%s (0x%08lx)", spname->sp_Data, spname->sp_Data))
  268.  
  269.    /* Check for mandatory DATA property */
  270.    if (spdata = FindProp(tmppi->tmppi_IFFHandle, ID_TMIC, ID_DATA)) {
  271.     struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  272.     struct IconDATAChunk *idc = spdata->sp_Data;
  273.  
  274.     ICON_LOG(LOG4(Data1, "ID 0x%08lx Exec 0x%08lx Image 0x%08lx Sound 0x%08lx",
  275.                   idc->idc_Standard.sdc_ID, idc->idc_ExecObject,
  276.                   idc->idc_ImageObject, idc->idc_SoundObject))
  277.     ICON_LOG(LOG3(Data2, "Flags 0x%08lx Left %ld Top %ld",
  278.                   idc->idc_Standard.sdc_Flags, idc->idc_LeftEdge,
  279.                   idc->idc_TopEdge))
  280.  
  281.     /* Set new name and ID */
  282.     SetAttrs(obj, TMA_Name, spname->sp_Data,
  283.                   TMA_ID,   idc->idc_Standard.sdc_ID,
  284.                   TAG_DONE);
  285.  
  286.     /* Copy values from data chunk */
  287.     icd->icd_Flags    = idc->idc_Standard.sdc_Flags & DATA_ICONF_MASK;
  288.     icd->icd_LeftEdge = idc->idc_LeftEdge;
  289.     icd->icd_TopEdge  = idc->idc_TopEdge;
  290.  
  291.     icd->icd_ExecObject  = AttachObject(tmppi->tmppi_Lists[TMOBJTYPE_EXEC],
  292.                                         obj, idc->idc_ExecObject);
  293.     icd->icd_ImageObject = AttachObject(tmppi->tmppi_Lists[TMOBJTYPE_IMAGE],
  294.                                         obj, idc->idc_ImageObject);
  295.     icd->icd_SoundObject = AttachObject(tmppi->tmppi_Lists[TMOBJTYPE_SOUND],
  296.                                         obj, idc->idc_SoundObject);
  297.  
  298.     /* All OK */
  299.     rc = TRUE;
  300.    }
  301.   }
  302.  }
  303.  
  304.  ICON_LOG(LOG1(Result, "%ld", rc))
  305.  
  306.  return(rc);
  307. }
  308.  
  309. /* Icon class method: TMM_WriteIFF */
  310. #undef  DEBUGFUNCTION
  311. #define DEBUGFUNCTION IconClassWriteIFF
  312. static ULONG IconClassWriteIFF(Class *cl, Object *obj,
  313.                                struct TMP_WriteIFF *tmpwi)
  314. {
  315.  struct IconClassData *icd  = TYPED_INST_DATA(cl, obj);
  316.  struct IconDATAChunk  idc;
  317.  BOOL                  rc;
  318.  
  319.  ICON_LOG(LOG1(IFFHandle, "0x%08lx", tmpwi->tmpwi_IFFHandle))
  320.  
  321.  /* Initialize DATA chunk (use object addresses as IDs) */
  322.  idc.idc_Standard.sdc_ID    = (ULONG) obj;
  323.  idc.idc_Standard.sdc_Flags = icd->icd_Flags;
  324.  idc.idc_LeftEdge           = icd->icd_LeftEdge;
  325.  idc.idc_TopEdge            = icd->icd_TopEdge;
  326.  idc.idc_ExecObject         = (ULONG) (icd->icd_ExecObject  ?
  327.                                         icd->icd_ExecObject->ad_Object  :
  328.                                         NULL);
  329.  idc.idc_ImageObject        = (ULONG) (icd->icd_ImageObject ?
  330.                                         icd->icd_ImageObject->ad_Object :
  331.                                         NULL);
  332.  idc.idc_SoundObject        = (ULONG) (icd->icd_SoundObject ?
  333.                                         icd->icd_SoundObject->ad_Object :
  334.                                         NULL);
  335.  
  336.  /* a) Forward message to SuperClass first */
  337.  /* b) Push DATA chunk                     */
  338.  rc = DoSuperMethodA(cl, obj, (Msg) tmpwi) &&
  339.       WriteProperty(tmpwi->tmpwi_IFFHandle, ID_DATA, &idc,
  340.                     sizeof(struct IconDATAChunk));
  341.  
  342.  ICON_LOG(LOG1(Result, "%ld", rc))
  343.  
  344.  return(rc);
  345. }
  346.  
  347. /* Icon class method: TMM_WBArg */
  348. #undef  DEBUGFUNCTION
  349. #define DEBUGFUNCTION IconClassWBArg
  350. static ULONG IconClassWBArg(Class *cl, Object *obj, struct TMP_WBArg *tmpwa)
  351. {
  352.  ULONG rc;
  353.  
  354.  ICON_LOG(LOG1(WBArg, "0x%08lx", tmpwa->tmpwa_Argument))
  355.  
  356.  /* First forward method to SuperClass */
  357.  if (rc = DoSuperMethodA(cl, obj, (Msg) tmpwa)) {
  358.   Object *exec;
  359.  
  360.   ICON_LOG(LOG0(Creating objects))
  361.  
  362.   /* Create exec object from WBArg */
  363.   if (exec = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_EXEC],
  364.                                   (Msg) tmpwa)) {
  365.    Object *image;
  366.  
  367.    ICON_LOG(LOG1(Exec, "0x%08lx", exec))
  368.  
  369.    /* Create image object from WBArg */
  370.    if (image = (Object *) DoMethodA(tmpwa->tmpwa_Lists[TMOBJTYPE_IMAGE],
  371.                                     (Msg) tmpwa)) {
  372.     struct IconClassData *icd = TYPED_INST_DATA(cl, obj);
  373.  
  374.     ICON_LOG(LOG1(Image, "0x%08lx", image))
  375.  
  376.     /* Attach new objects */
  377.     SetAttrs(icd->icd_ExecDrop,  TMA_Object, exec,  TAG_DONE);
  378.     SetAttrs(icd->icd_ImageDrop, TMA_Object, image, TAG_DONE);
  379.    }
  380.   }
  381.  }
  382.  
  383.  ICON_LOG(LOG1(Result, "0x%08lx", rc))
  384.  
  385.  return(rc);
  386. }
  387.  
  388. /* Icon class method dispatcher */
  389. #undef  DEBUGFUNCTION
  390. #define DEBUGFUNCTION IconClassDispatcher
  391. __geta4 static ULONG IconClassDispatcher(__a0 Class *cl, __a2 Object *obj,
  392.                                          __a1 Msg msg)
  393. {
  394.  ULONG rc;
  395.  
  396.  ICON_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  397.                cl, obj, msg))
  398.  
  399.  switch(msg->MethodID) {
  400.   /* BOOPSI methods */
  401.   case OM_NEW:
  402.    rc = IconClassNew(cl, obj, (struct opSet *) msg);
  403.    break;
  404.  
  405.   case OM_DISPOSE:
  406.    rc = IconClassDispose(cl, obj, msg);
  407.    break;
  408.  
  409.   /* TM methods */
  410.   case TMM_Finish:
  411.    rc = IconClassFinish(cl, obj, (struct TMP_Finish *) msg);
  412.    break;
  413.  
  414.   case TMM_Notify:
  415.    rc = IconClassNotify(cl, obj, (struct TMP_Notify *) msg);
  416.    break;
  417.  
  418.   case TMM_Edit:
  419.    rc = IconClassEdit(cl, obj, (struct TMP_Edit *) msg);
  420.    break;
  421.  
  422.   case TMM_ParseIFF:
  423.    rc = IconClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  424.    break;
  425.  
  426.   case TMM_WriteIFF:
  427.    rc = IconClassWriteIFF(cl, obj, (struct TMP_WriteIFF *) msg);
  428.    break;
  429.  
  430.   case TMM_WBArg:
  431.    rc = IconClassWBArg(cl, obj, (struct TMP_WBArg *) msg);
  432.    break;
  433.  
  434.   /* Unknown method -> delegate to SuperClass */
  435.   default:
  436.    rc = DoSuperMethodA(cl, obj, msg);
  437.    break;
  438.  }
  439.  
  440.  return(rc);
  441. }
  442.  
  443. /* Create Icon class */
  444. #undef  DEBUGFUNCTION
  445. #define DEBUGFUNCTION CreateIconClass
  446. struct MUI_CustomClass *CreateIconClass(void)
  447. {
  448.  struct MUI_CustomClass *rc;
  449.  
  450.  /* Create class */
  451.  if (rc = MUI_CreateCustomClass(NULL, NULL, BaseClass,
  452.                                 sizeof(struct IconClassData),
  453.                                 IconClassDispatcher)) {
  454.  
  455.   /* Localize strings */
  456.   TextTitle       = TranslateString(LOCALE_TEXT_ICON_TITLE_STR,
  457.                                     LOCALE_TEXT_ICON_TITLE);
  458.   HelpExecObject  = TranslateString(LOCALE_HELP_ICON_EXEC_OBJECT_STR,
  459.                                     LOCALE_HELP_ICON_EXEC_OBJECT);
  460.   HelpImageObject = TranslateString(LOCALE_HELP_ICON_IMAGE_OBJECT_STR,
  461.                                     LOCALE_HELP_ICON_IMAGE_OBJECT);
  462.   HelpSoundObject = TranslateString(LOCALE_HELP_ICON_SOUND_OBJECT_STR,
  463.                                     LOCALE_HELP_ICON_SOUND_OBJECT);
  464.   HelpPosition    = TranslateString(LOCALE_HELP_ICON_POSITION_STR,
  465.                                     LOCALE_HELP_ICON_POSITION);
  466.   TextShowName    = TranslateString(LOCALE_TEXT_ICON_SHOW_NAME_STR,
  467.                                     LOCALE_TEXT_ICON_SHOW_NAME);
  468.   HelpShowName    = TranslateString(LOCALE_HELP_ICON_SHOW_NAME_STR,
  469.                                     LOCALE_HELP_ICON_SHOW_NAME);
  470.  }
  471.  
  472.  ICON_LOG(LOG1(Result, "0x%08lx", rc))
  473.  
  474.  return(rc);
  475. }
  476.